home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / x / gui / xfract.lha / xfract / cmn_mntncode.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-06-27  |  9.6 KB  |  355 lines

  1. /*****************************************************************************
  2. /* FILE        : cmn_mntncode.c
  3. /* AUTHOR    : Paul Sharpe @ DEC (OSCR-Europe, Reading, England).
  4. /* DATE        : July 20, 1989
  5. /* FUNCTION    : Common code in the mountain-generating programs.
  6. /* INSPIRATION    : 'The Science Of Fractal Images.'
  7. /*
  8. /*   Copyright (c) Digital Equipment Corporation 1990  All rights reserved.
  9. /*   Copyright is claimed in the computer program and user interface thereof.
  10. /*
  11. /*   Digital Equipment Corporation cannot accept any responsibility for
  12. /*   use, misuse, or abuse of this software.
  13. /*
  14. /*****************************************************************************/
  15.  
  16. #include <stdio.h>
  17. #include <math.h>
  18.  
  19. #include <X11/Xlib.h>
  20. #include <X11/Xatom.h>
  21. #include <X11/Xutil.h>
  22.  
  23. #include "xpt.h"
  24.  
  25. #define    RECALC        "New Mountains"
  26. #define QUIT        "Quit"
  27.  
  28. #define PNTS(i,px,py)    {pnts[(i)].x=(px);pnts[(i)].y=(py);}
  29.  
  30. #define ABS(x)        (((x)<0) ? -(x) : (x))
  31. #define SW(s)           (XTextWidth(fs,(s),strlen((s))))
  32.  
  33. int    screenwidth, screenheight;
  34. int    basey;
  35. int    square;
  36.  
  37. struct mntn {
  38.     double    **elevs;
  39.     int        **px;
  40.     int        **py;
  41. } mntndata;
  42. extern double    sigma, H;
  43. extern int    level;
  44.  
  45. extern char    *calloc();
  46. extern char    *bckgrnd, *progtitle, *iconfile;
  47.  
  48. Display        *dsply;        /* The display connected to. */
  49. Window        wndw;        /* The window in which to display */
  50. Window        hwndw,swndw, twndw, rwndw, qwndw;
  51. GC         maingc, mntngc,seagc, bttngc;
  52. unsigned long    mc;        /* Mountain colour(s?) */
  53. Colormap    clmap;        /* colourmap for colour display. */
  54. Pixmap        pntrbtm;
  55. Font        fnt;
  56. XFontStruct    *fs;
  57. int        wdth, hght;
  58. int        depth;        /* Display depth: no. of planes. */
  59. int        numcols;
  60. int        mntndist, scrndist;
  61.  
  62. static char    *titles[] = {"Brownian Motion","Mountains",
  63.                  "Paul Sharpe @ DEC"};
  64.  
  65. extern struct opts     args[];
  66.  
  67. init_cmn()
  68. {
  69.     sigma = atof(ARGS(11));    /* Scaling, or standard deviation. */
  70.     H = atof(ARGS(10));        /* Sets the fractal dimension. */
  71.     numcols = atoi(ARGS(7));
  72.     if ((level = atoi(ARGS(12))) < 1)
  73.     level = 1;
  74.     square = (1<<level) + 1;
  75.  
  76.     init_arrays();
  77. }
  78.  
  79. init_arrays()
  80. {
  81. register int    i;
  82.  
  83.     mntndata.elevs =(double **)calloc(square,(unsigned)sizeof(double *));
  84.     mntndata.px = (int **)calloc(square,(unsigned)sizeof(int *));
  85.     mntndata.py = (int **)calloc(square,(unsigned)sizeof(int *));
  86.     for (i=0; i<square; i++) {
  87.         mntndata.elevs[i] = (double *)calloc(square,(unsigned)sizeof(double));
  88.         mntndata.px[i] = (int *)calloc(square,(unsigned)sizeof(int));
  89.         mntndata.py[i] = (int *)calloc(square,(unsigned)sizeof(int));
  90.     }
  91. }
  92.  
  93. process_events()
  94. {
  95.     for(;;)
  96.     do_event();
  97. }
  98.  
  99. do_event()
  100. {
  101. XEvent        event;
  102.  
  103.     XNextEvent(dsply, &event);
  104.     switch (event.type) {
  105.     case Expose:
  106.     case GraphicsExpose:
  107.         if (event.xexpose.count == 0)
  108.             do_expose((XExposeEvent *)&event);
  109.         break;
  110.     case ButtonPress:    /* Get a new Dimension, and redisplay! */
  111.         do_bttn((XButtonPressedEvent *)&event);
  112.         break;
  113.     default:
  114.         break;
  115.     }
  116. }
  117.  
  118. do_expose(event)
  119. XExposeEvent    *event;
  120. {
  121.     if (event->window == qwndw)
  122.     XDrawString(dsply,qwndw,bttngc,2,fs->ascent+2,QUIT,strlen(QUIT));
  123.     if (event->window == rwndw)
  124.     XDrawString(dsply,rwndw,bttngc,2,fs->ascent+2,RECALC,strlen(RECALC));
  125.     if (event->window == swndw)
  126.     draw_scale();
  127.     if (event->window == hwndw)
  128.     draw_H();
  129.     if (event->window == twndw)
  130.     draw_titles();
  131.     if (event->window == wndw)
  132.     display();
  133. }
  134.  
  135. do_bttn(bttn)
  136. XButtonPressedEvent     *bttn;
  137. {
  138.     if (bttn->window == qwndw)
  139.     exit(1);
  140.     if (bttn->window == rwndw) {
  141.     gen_mntndata(mntndata.elevs,square, (double)(square-5));
  142.     elevs2coords();
  143.     XClearWindow(dsply,wndw);
  144.     display();
  145.     }
  146.     if (bttn->window == swndw) {
  147.     if (bttn->x < 300)
  148.         H = (double)((double)(bttn->x)/(double)100.0);
  149.     XClearWindow(dsply,swndw);
  150.     XClearWindow(dsply,hwndw);
  151.     draw_scale();
  152.     draw_H();
  153.     }
  154. }
  155.  
  156. draw_face(pnts, col)
  157. XPoint    pnts[];
  158. int    col;        /* Colour for the filled area. */
  159. {
  160. int        dy;
  161. static long    lastcol = -1;
  162.  
  163. /* Pseudo-shading determined by gradient of the face. */
  164.     if (col >= 0 && depth > 1 && numcols > 1) {
  165.     dy = (int)(pnts[1].y - pnts[3].y);
  166.     col = (pnts[0].y - pnts[2].y) + (20 - ABS(dy));
  167.         if (col >= numcols)
  168.         col = numcols - 1;
  169.     }
  170.     if (col < 0)
  171.     col = 0;
  172.  
  173. /* Try to speed up the display by only setting colours as necessary... */
  174.     if (col != lastcol) {
  175.     XSetForeground(dsply,mntngc,col);
  176.     lastcol = col;
  177.     }
  178.     XFillPolygon(dsply,wndw,mntngc,pnts,4,Nonconvex,CoordModeOrigin);
  179.  
  180. /* Draw the gridcolour lines around the filled quadilateral... */
  181.     if (numcols <= 1 || depth <= 1) {
  182.     pnts[4].x = pnts[0].x;
  183.     pnts[4].y = pnts[0].y;
  184.     XDrawLines(dsply,wndw,maingc,pnts,5,CoordModeOrigin);
  185.     }
  186. }
  187.  
  188. init_X()
  189. {
  190. int             x,y, len;
  191. Font            fnt;
  192. extern Window    xpt_window();
  193. extern Display  *xpt_open_display();
  194.  
  195.     dsply = xpt_open_display(ARGS(0));
  196.  
  197.     depth = DEFDEPTH(dsply);
  198.  
  199. /* If we have multi-planes, allow for some shading of the mountains. */
  200.     if (depth == 1 || numcols <= 1)
  201.     clmap = DefaultColormapOfScreen(DefaultScreenOfDisplay(dsply));
  202.     else {
  203.     clmap = XCreateColormap(dsply,ROOTWNDW(dsply),DefaultVisualOfScreen(DefaultScreenOfDisplay(dsply)),AllocNone);
  204.     set_cols(numcols);
  205.     }
  206.     set_GCs();
  207.  
  208.     x = screenwidth + 20;
  209.     y = screenheight + 20;
  210.     DEBUG(("Creating window: %dx%d.\n",x,y));
  211.     wndw  = xpt_window(dsply,ROOTWNDW(dsply),0,0,x,y,0);
  212.     XSetWindowColormap(dsply,wndw,clmap);
  213.     len = DisplayWidth(dsply,DefaultScreen(dsply));
  214.     if (x > len)
  215.     x = len;
  216.     xpt_windowcols(dsply,wndw,maingc,clmap,ARGS(2),"white",bckgrnd);
  217.  
  218.     init_font();
  219.  
  220.     len = SW("0.000000");
  221.     hwndw = xpt_window(dsply,wndw,x-len-20,10,len,hght+2,ButtonPressMask);
  222.     xpt_windowcols(dsply,hwndw,bttngc,clmap,ARGS(4),ARGS(3),NULL);
  223.     swndw = xpt_window(dsply,wndw,x-len-300-20,10,300,hght+2,ButtonPressMask);
  224.     xpt_windowcols(dsply,swndw,bttngc,clmap,ARGS(4),ARGS(3),NULL);
  225.     set_pointer();        /* Create a Pixmap holding the arrow pointer. */
  226.  
  227. /* BUTTON: Recalculate and draw new mountains. */
  228.     len = SW(RECALC) + 2;
  229.     rwndw = xpt_window(dsply,wndw,x-len-20,hght+20,len,hght+4,ButtonPressMask);
  230.     xpt_windowcols(dsply,rwndw,bttngc,clmap,ARGS(4),ARGS(3),NULL);
  231.  
  232. /* BUTTON: Quit from mountain program. */
  233.     len = SW(QUIT) + 2;
  234.     qwndw = xpt_window(dsply,wndw,x-len-20,2*hght+30,len,hght+4,ButtonPressMask);
  235.     xpt_windowcols(dsply,qwndw,bttngc,clmap,ARGS(4),ARGS(3),NULL);
  236.  
  237. /* Title block for the mountains, author etc. */
  238.     len = XTextWidth(fs,titles[2],strlen(titles[2])) + 4;
  239.     twndw = xpt_window(dsply,wndw,10,10,len,3*hght+4,ButtonPressMask);
  240.     xpt_windowcols(dsply,twndw,bttngc,clmap,ARGS(4),ARGS(3),NULL);
  241.  
  242.     XMapSubwindows(dsply,wndw);
  243.     XMapWindow(dsply,wndw);
  244.  
  245.     xpt_icon(dsply,wndw,progtitle,iconfile);
  246. }
  247.  
  248. init_font()
  249. {
  250.     fnt = XLoadFont(dsply,ARGS(9));
  251.     XSetFont(dsply,bttngc,fnt);
  252.     fs = XQueryFont(dsply,fnt);
  253.     wdth = fs->max_bounds.width;
  254.     hght = 2 + fs->ascent + fs->descent;
  255. }
  256.  
  257. set_GCs()
  258. {
  259.     maingc = XDefaultGC(dsply,DefaultScreen(dsply));
  260.     XSetFunction(dsply,maingc,GXcopy);
  261.     XSetPlaneMask(dsply,maingc,AllPlanes);
  262.     XSetGraphicsExposures(dsply,maingc,True);
  263.     XSetForeground(dsply, maingc, xpt_colour(dsply,ARGS(1),clmap));
  264.     XSetBackground(dsply, maingc, xpt_colour(dsply,ARGS(2),clmap));
  265.  
  266.     bttngc = XCreateGC(dsply,ROOTWNDW(dsply),0,0);
  267.     XCopyGC(dsply,maingc,-1L,bttngc);
  268.     XSetForeground(dsply, bttngc, xpt_colour(dsply,ARGS(3),clmap));
  269.     XSetBackground(dsply, bttngc, xpt_colour(dsply,ARGS(4),clmap));
  270.  
  271.     seagc = XCreateGC(dsply,ROOTWNDW(dsply),0,0);
  272.     XCopyGC(dsply,maingc,-1L,seagc);
  273.     XSetForeground(dsply, seagc, xpt_colour(dsply,ARGS(5),clmap));
  274.  
  275.     mntngc = XCreateGC(dsply,ROOTWNDW(dsply),0,0);
  276.     XCopyGC(dsply,maingc,-1L,mntngc);
  277.     XSetForeground(dsply, mntngc,(mc = xpt_colour(dsply,ARGS(6),clmap)));
  278. }
  279.  
  280. set_cols(numcols)
  281. int    numcols;
  282. {
  283. int        i, dc;
  284. char        str[32], fmt[32];
  285. extern char    *index();
  286.  
  287. /* Spread the colours out along the available spectrum... */
  288.     sprintf(fmt,"#%s%s%s",(index(ARGS(8),'r')==NULL)?"0000":"%04x",
  289.               (index(ARGS(8),'g')==NULL)?"0000":"%04x",
  290.               (index(ARGS(8),'b')==NULL)?"0000":"%04x");
  291.     if (numcols > 1) {
  292.     dc = 65000/numcols;
  293.     for (i=1; i<=numcols; i++) {
  294.         sprintf(str,fmt,i*dc,i*dc,i*dc);
  295.         xpt_colour(dsply,str,clmap);
  296.     }
  297.     }
  298. }
  299.  
  300. draw_titles()
  301. {
  302. int    i, y;
  303.  
  304.     for (i=0; i<3; i++) {
  305.     y = i*hght + fs->ascent + 1;
  306.     XDrawString(dsply,twndw,bttngc,2,y,titles[i],strlen(titles[i]));
  307.     }
  308. }
  309.  
  310. draw_scale()
  311. {
  312. int    x, i;
  313.  
  314.     for (i=100; i<=200; i+=100) {
  315.     XDrawLine(dsply,swndw,bttngc,i,0,i,5);
  316.     XDrawLine(dsply,swndw,bttngc,i,hght,i,hght-5);
  317.     }
  318.     XDrawLine(dsply,swndw,bttngc,300,0,300,hght);
  319.     x = (int)floor(H * (double)100.0) - (hght/2);
  320.     XCopyArea(dsply,pntrbtm,swndw,bttngc,0,0,hght,hght,x,0);
  321. }
  322.  
  323. draw_H()
  324. {
  325. char    str[16];
  326.  
  327.     sprintf(str,"%f",H);
  328.     XDrawString(dsply,hwndw,bttngc,2,fs->ascent+2,str,strlen(str));
  329. }
  330.  
  331. set_pointer()
  332. {
  333. XPoint    pnts[7];
  334.  
  335.     pntrbtm = XCreatePixmap(dsply,wndw,hght,hght,depth);
  336.     if (pntrbtm == 0) {
  337.     fprintf(stderr,"FATAL: Can't create pointer pixmap!\n");
  338.     exit(2);
  339.     }
  340. /* Set the foreground to the normal button text background colour. */
  341.     XSetForeground(dsply, bttngc, xpt_colour(dsply,ARGS(4),clmap));
  342. /* Clear the Pixmap by filling it as a rectangle with the background colour. */
  343.     XFillRectangle(dsply, pntrbtm,bttngc,0,0,hght,hght);
  344. /* Reset the normal button text foreground colour. */
  345.     XSetForeground(dsply, bttngc, xpt_colour(dsply,ARGS(3),clmap));
  346.     pnts[0].x = hght/2;        pnts[0].y = 0;
  347.     pnts[1].x = 0;        pnts[1].y = hght/2;
  348.     pnts[2].x = hght/4;        pnts[2].y = pnts[1].y;
  349.     pnts[3].x = pnts[2].x;    pnts[3].y = hght;
  350.     pnts[4].x = 3*hght/4;    pnts[4].y = pnts[3].y;
  351.     pnts[5].x = pnts[4].x;    pnts[5].y = pnts[1].y;
  352.     pnts[6].x = hght;        pnts[6].y = pnts[5].y;
  353.     XFillPolygon(dsply,pntrbtm,bttngc,pnts,7,Nonconvex,CoordModeOrigin);
  354. }
  355.